# 阿里云天池学习赛-测测你的一见钟情指数
# Author: Liu Yuanxi
# 2021-12

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sb
from sklearn.neural_network import MLPClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
import imblearn as ibl

# 读取数据
data = pd.read_csv('/Users/liuyuanxi/学习/华为智能基座/huawei-smart-base-learning/一见钟情指数/数据集/speed_dating_train.csv',
                   encoding = 'UTF-8')
print('训练集数据：', data)

# 数据分析
# 查看表格规模
# print('\n表格规模：', np.shape(data))
# 查看数据空缺值
print('\n每一项空缺值占比：')
missing_percent = data.isnull().sum() * 100 / len(data)
print(missing_percent.sort_values())

# 数据分析
# 第一张图：通过该活动成功脱单的人
plt.subplot(1, 2, 1)
groupSize_matched = data.match.value_counts().values
signs = ['Single:' + str(round(groupSize_matched[0] * 100 / sum(groupSize_matched), 2)) + '%', 'Matched:' + str(round
        (groupSize_matched[1] * 100 /sum(groupSize_matched), 2)) + '%']
plt.pie(groupSize_matched, labels = signs)
# 第二张图：女生中成功脱单的人与男生中成功脱单的人
plt.subplot(1, 2, 2)
groupSize_genderMatched = data[data.match == 1].gender.value_counts().values
maleMatchedPercent = groupSize_genderMatched[0] * 100 / sum(groupSize_genderMatched)
femaleMatchedPercent = groupSize_genderMatched[1] * 100 / sum(groupSize_genderMatched)
signs = ['Male:' + str(round(maleMatchedPercent, 2)) + '%', 'Female:' + str(round(femaleMatchedPercent, 2)) + '%']
plt.pie(groupSize_genderMatched, labels = signs)
# plt.savefig('Figure0.png')
plt.subplot(1, 1, 1)
# 参加该活动的人的年龄分布情况
age = data[np.isfinite(data['age'])]['age']
plt.hist(age, bins = 35)
plt.xlabel('Age')
plt.ylabel('Frequency')
# plt.savefig('Figure1.png')
# plt.show()
# 画出热力图分析各特征相关性
date_data = data[['iid', 'gender', 'condtn', 'round', 'position', 'match', 'int_corr', 'samerace', 'age_o', 'race_o',
                  'pf_o_att', 'dec_o', 'field_cd', 'mn_sat', 'tuition', 'race', 'imprace', 'from', 'zipcode', 'income',
                  'goal', 'career_c', 'sports', 'tvsports', 'exercise', 'dining', 'art', 'hiking', 'gaming', 'clubbing',
                  'reading', 'tv', 'theater', 'movies', 'concerts', 'music', 'shopping', 'yoga', 'exphappy',
                  'expnum', 'attr1_1', 'sinc1_1', 'intel1_1', 'fun1_1', 'amb1_1', 'shar1_1', 'attr2_1', 'sinc2_1',
                  'fun2_1', 'shar2_1', 'attr3_1', 'sinc3_1', 'intel3_1', 'fun3_1', 'amb3_1', 'attr4_1', 'sinc4_1',
                  'intel4_1', 'fun4_1', 'amb4_1', 'shar4_1', 'attr5_1', 'sinc5_1','intel5_1', 'fun5_1', 'amb5_1']]
plt.subplots(figsize = (25, 20))
corr = date_data.corr()
sb.heatmap(corr, xticklabels = corr.columns.values, yticklabels = corr.columns.values)
# plt.savefig('Heatmap.png')

# 经过上述画图分析选定如下特征
# 年龄、性别、职业、外观吸引力、聪明程度、幽默成都、分享欲、真诚、目标、民族、地区、对音乐的喜好成都、对运动的喜好程度
choice_data = data[['age_o', 'gender', 'attr_o', 'intel_o', 'fun_o', 'amb_o', 'shar_o', 'match', 'sinc_o',
                    'music', 'sports', 'goal', 'race_o', 'position']]
# choice_data.dropna(inplace = True) # 处理空缺值
choice_data = choice_data.fillna(value = 0)
x = choice_data[['age_o', 'gender', 'attr_o', 'intel_o', 'fun_o', 'amb_o', 'shar_o', 'sinc_o', 'music', 'sports', 'goal'
                , 'race_o', 'position']]
y = choice_data[['match']]
oversample = ibl.over_sampling.SVMSMOTE()
x, y = oversample.fit_resample(x, y)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
# 构建模型，使用神经网络
model = MLPClassifier(solver = 'adam', activation = 'tanh', hidden_layer_sizes = (128, 128, 256, 256, 128, 128))
model.fit(x_train, y_train)
predict = model.predict(x_test)
print('神经网络预测结果：\n', predict)
print('模型评价：\n', classification_report(predict, y_test))
acc_per = 0
y_test = np.array(y_test)
for i in range(len(y_test)):
    if y_test[i][0] == predict[i]:
        acc_per += 1
acc_per = acc_per * 100 / len(y_test)
print('预测准确率：%d%%'%acc_per)
# 使用训练出来的模型进行预测
# 读取预测数据集
pred_data = pd.read_csv('/Users/liuyuanxi/学习/华为智能基座/huawei-smart-base-learning/一见钟情指数/数据集/speed_dating_test.csv'
                        , encoding = 'UTF-8')
print('预测集数据：', pred_data)
choice_pred_data = pred_data[['age_o', 'gender', 'attr_o', 'intel_o', 'fun_o', 'amb_o', 'shar_o', 'sinc_o',
                              'uid', 'music', 'sports', 'goal', 'race_o', 'position']]
# 处理缺失值
# choice_pred_data.dropna(inplace = True)
choice_pred_data = choice_pred_data.fillna(axis = 1, method = 'ffill')
x_pred = choice_pred_data[['age_o', 'gender', 'attr_o', 'intel_o', 'fun_o', 'amb_o', 'shar_o', 'sinc_o', 'music'
                           , 'sports', 'goal', 'race_o', 'position']]
y_pred = model.predict(x_pred)
print('预测结果：\n', y_pred)
# 将预测结果写入 CSV 文件
predict_result = pd.DataFrame({'uid': choice_pred_data['uid'], 'match': y_pred}, dtype = int)
predict_result.to_csv('predict_result.csv', index = False, sep = ',')